package view;
import java.rmi.RemoteException;

import javax.swing.JFrame;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import controller.FirewallSession;

import server.FirewallException;
import server.NotExpertException;
import server.ReadWriteException;
import server.Rule;
import server.RulesTableType;

/**
 * Class is responsible for rules table.
 * Table contains all elements that are defined in inherited class.
 */
public class RulesAdvancedTable extends AbstractRulesTable
{
	/**
	 * Serial version ID - for serialization
	 */
	private static final long serialVersionUID = -3740562357093729559L;

	/**
	 * Column names
	 */
	protected final static String columnNames[] =
			{"Id", "IP", "Port", "Protocol", "Action" };
	
	/**
	 * Current advanced rule table in IN directions.
	 */
	public static RulesAdvancedTable currentInRulesTable = null;
	
	/**
	 * Current advanced rule table in OUT directions.
	 */
	public static RulesAdvancedTable currentOutRulesTable = null;
	
	/**
	 * C'tor - Table with specified controller and direction is created.
	 * The tables are build in way, that only one row in one of two tables can be selected.
	 * @param ui	- the controller for the system actions
	 */
	public RulesAdvancedTable(RulesTableType type,FirewallSession ui)
	{	    
		super(type, Settings.DEFAULT_RULES_WINDOW_DEPTH, columnNames.length,ui);
		
		switch(type)
		{
		/* Table for IN rules */
		case IN:
			currentInRulesTable = this;
			
			/* Click on this table clear selection in OUT table */
			currentInRulesTable.getSelectionModel().addListSelectionListener(new ListSelectionListener()
			{
				public void valueChanged(ListSelectionEvent event)
				{
					currentOutRulesTable.clearSelection();
				}	
			});
			break;
		/* Table for OUT rules */
		case OUT:
			currentOutRulesTable = this;
			
			/* Click on this table clear selection in IN table */
			currentOutRulesTable.getSelectionModel().addListSelectionListener(new ListSelectionListener()
			{
				public void valueChanged(ListSelectionEvent event)
				{
					currentInRulesTable.clearSelection();
				}	
			});
			break;
		}
		
		/* Fill the tables with data from FW */
		build();
	}
	
	/**
	 * Returns the table columns names
	 * @return - the table columns names
	 */
	protected String[] getColumnsNames() 
	{
		return columnNames;
	}

	/**
	 * Add the rule to the FW data base.
	 * @param direction - direction of the rule
	 * @param rule		- the rule data
	 */
	public void addRule(RulesTableType direction, Rule rule) {
		try {
			UI.addRule(direction, Settings.ruleset, rule);
		} catch (RemoteException e) {
			ErrorFrame.AddError("RMI connection problems: failed to add the rule", new JFrame());
		} catch (FirewallException e) {
			ErrorFrame.AddError("Failed to add the rule:" + e.getMessage(), new JFrame());
		} catch (ReadWriteException e) {
			ErrorFrame.AddError("Failed to add the rule:" + e.getMessage(), new JFrame());
		} catch (NotExpertException e) {
			ErrorFrame.AddError("Failed to add the rule:" + e.getMessage(), new JFrame());
		}
		
		/* Update the tables with data from FW */
		build();
	}
}


